#include "ShowAndGuess.h"

#include <fstream>
#include <iostream>
#include <cassert>
#include <vector>
#include <unordered_set>
#include <ctime>
#include <cstdlib>

#include <QPushButton>
#include <QVBoxLayout>
#include <QSizePolicy>
#include "CountdownWidget.h"
#include <QEvent>
#include <QFile>
#include <QTextStream>

#include <spdlog/spdlog.h>

static const std::string gFilePath = "res/ShowAndGuess.txt";
static const QString gRuleFilePath = "res/ShowAndGuessRules.txt";

namespace {
QString readTxtFile(const QString& filePath) {
    QString fileContent;
    QFile file(filePath);

    if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QTextStream in(&file);
        fileContent = in.readAll();
        file.close();
    } else {
        //qWarning() << "无法打开文件: " << filePath;
        SPDLOG_ERROR("无法打开文件: {}", filePath.toStdString());
    }

    return fileContent;
}

int generateUniqueRandomNumber(int range) {
    static std::unordered_set<int> usedNumbers;
    static std::vector<int> allNumbers;

    // 如果是第一次调用函数，初始化所有数字的向量
    if (allNumbers.empty()) {
        for (int i = 0; i < range; ++i) {
            allNumbers.push_back(i);
        }
    }

    // 如果已经生成了所有的随机数，返回 -1表示结束
    if (usedNumbers.size() == range) {
        return -1;
    }

    // 初始化随机数生成器（只在第一次调用时执行）
    static bool isRandomInitialized = false;
    if (!isRandomInitialized) {
        srand(static_cast<unsigned int>(time(nullptr)));
        isRandomInitialized = true;
    }

    int randomIndex;
    do {
        randomIndex = rand() % allNumbers.size();
    } while (usedNumbers.find(allNumbers[randomIndex])!= usedNumbers.end());

    int randomNumber = allNumbers[randomIndex];
    usedNumbers.insert(randomNumber);

    return randomNumber;
}

}

ShowAndGuess::ShowAndGuess():
    countdownWidget(this,60){
    std::cout<<"ShowAndGuess()"<<std::endl;
    passButton.setText("过");
    connect(&passButton, &QPushButton::clicked, this, &ShowAndGuess::onPassButtonClicked);
    doneButton.setText("完成");
    connect(&doneButton, &QPushButton::clicked, this, &ShowAndGuess::onDoneButtonClicked);

    //contentButton.setText("这里显示内容");
    contentButton.setText(readTxtFile(gRuleFilePath));
    contentButton.setStyleSheet("QPushButton {"
                         "    background-color: red; /* 设置背景色为红色 */"
                         "    color: white; /* 设置文本颜色为白色 */"
                         "}");
    QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
    sizePolicy.setHorizontalStretch(3);
    contentButton.setSizePolicy(sizePolicy);
    QFont font;
    font.setPointSize(20);
    font.setBold(true);
    contentButton.setFont(font);

    leftLayout.addWidget(&countdownWidget);
    leftLayout.addWidget(&passButton);
    leftLayout.addWidget(&doneButton);

    mainLayout.addLayout(&leftLayout);
    mainLayout.addWidget(&contentButton);

    this->setLayout(&mainLayout);

    ReadWords();
}

ShowAndGuess::~ShowAndGuess(){
    SPDLOG_TRACE("~ShowAndGuess");
}   

void ShowAndGuess::ReadWords(){
    std::ifstream file(gFilePath);  
    if (file.is_open())
    {
        std::string line;
        while (std::getline(file, line))
        {
            words.push_back(line);
        }
        file.close();
    }
    else
    {
        std::cout<<"open failed!"<<std::endl;
        //assert(false);
    }
}

std::string ShowAndGuess::GetRandomWord(){
    if(words.empty()) {
        return "没有单词了";
    }   

    //int index = rand() % words.size();
    int index = generateUniqueRandomNumber(words.size());
    SPDLOG_INFO("index: {}", index);
    if(index == -1) {
        index = 0;
    }
    return words[index];
}

void ShowAndGuess::onDoneButtonClicked(){
    contentButton.setText(QString::fromStdString(GetRandomWord()));
    countdownWidget.RestartCounter();
}

void ShowAndGuess::onPassButtonClicked(){
    contentButton.setText(QString::fromStdString(GetRandomWord()));
    countdownWidget.RestartCounter();
}

#include <map>

static std::map<int, std::string> eventTypeToString = {
    {QEvent::None, "None"},
    {QEvent::Timer, "Timer"},
    {QEvent::MouseButtonPress, "MouseButtonPress"},
    {QEvent::MouseButtonRelease, "MouseButtonRelease"},
    {QEvent::MouseButtonDblClick, "MouseButtonDblClick"},
    {QEvent::MouseMove, "MouseMove"},
    {QEvent::KeyPress, "KeyPress"},
    {QEvent::KeyRelease, "KeyRelease"},
    {QEvent::FocusIn, "FocusIn"},
    {QEvent::FocusOut, "FocusOut"},
    // 可以根据需要添加更多的事件类型和名称
};

bool ShowAndGuess::eventFilter(QObject *watched, QEvent *event)
{
    //std::cout<<"eventFilter"<<std::endl;
    if (watched->inherits("QPushButton") && event->type() == QEvent::MouseButtonPress)
    {
        // QPushButton *button = static_cast<QPushButton *>(watched);
        // std::cout<<"button pressed"<<button->text().toStdString()<<std::endl;
        // int eventType = event->type();
        // auto it = eventTypeToString.find(eventType);
        // if (it!= eventTypeToString.end()) {
        //     std::cout << "Catch event: " << it->second << std::endl;
        // } else {
        //     std::cout << "Catch unknown event: " << eventType << std::endl;
        // }

        onDoneButtonClicked();
    }
    return QWidget::eventFilter(watched, event);
}